<!DOCTYPE html>
<html lang="zh">

<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>
    
    文件的读写 - DSRBLOG
    
  </title>
  

  
  
  <link href="atom.xml" rel="alternate" title="DSRBLOG" type="application/atom+xml">
  <link rel="stylesheet" href="asset/css/style.min.css">
  <link rel="stylesheet" href="asset/css/doc.css">
  <script src="asset/app.js"></script>


</head>

<body> <section class="ct-body">
	<div class="container">
		<div class="columns is-variable bd-klmn-columns is-4 is-centered">
			<div class="column is-four-fifths">
				<div class="post-body single-content">
					
					<h1 class="title">
						文件的读写
					</h1>


					<div class="media">
						
						
						<div class="media-content">
							<div class="content">
								<p>
									<span class="date">2022/02/09 03:34 上午</span>
									

									

									<br />
									<span class="tran-tags">Tags:</span>&nbsp;
									
									<a class="tag is-link is-light">#C语言</a>
									

								</p>
							</div>
						</div>

					</div>
				</div>
				<article class="markdown-body single-content">
					<h2><a id="%E5%AD%97%E7%AC%A6%E8%AF%BB%E5%86%99%E5%87%BD%E6%95%B0%EF%BC%88ascii%E6%96%87%E4%BB%B6%EF%BC%89" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>字符读写函数（ASCII文件）</h2>
<h3><a id="fgetc%E5%87%BD%E6%95%B0" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>fgetc()函数</h3>
<p>用<code>fgetc()</code>函数从文件读取一个字符</p>
<h4><a id="%E8%B0%83%E7%94%A8%E5%BD%A2%E5%BC%8F" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>调用形式</h4>
<pre class="line-numbers"><code class="language-c">ch = fgetc(fp);
</code></pre>
<h4><a id="%E5%87%BD%E6%95%B0%E5%8A%9F%E8%83%BD" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>函数功能</h4>
<ul>
<li><code>fgetc()</code>函数带回一个字符，并赋值给<code>ch</code></li>
<li>文件被打开时，文件内部位置指针指向文件的第一个字节，使用<code>fgetc()</code>函数读入一个字节后，位置指针自动向后移动一个字节</li>
</ul>
<h4><a id="%E8%BF%94%E5%9B%9E%E5%80%BC" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>返回值</h4>
<p>如果在执行<code>fgetc()</code>函数读取字符时遇到文件结束符，返回文件结束标志EOF（即-1）</p>
<h3><a id="fputc%E5%87%BD%E6%95%B0" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>fputc()函数</h3>
<p>用<code>fputc()</code>函数向文件写入一个字符</p>
<h4><a id="%E8%B0%83%E7%94%A8%E5%BD%A2%E5%BC%8F" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>调用形式</h4>
<pre class="line-numbers"><code class="language-c">fputc(ch, fp);
</code></pre>
<h4><a id="%E5%87%BD%E6%95%B0%E5%8A%9F%E8%83%BD" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>函数功能</h4>
<p>将字符（<code>ch</code>的值）输出到<code>fp</code>所指向的文件中去</p>
<h4><a id="%E8%BF%94%E5%9B%9E%E5%80%BC" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>返回值</h4>
<ul>
<li>如果输出成功，返回值是输出的字符</li>
<li>如果输出失败，返回值为EOF（即-1）</li>
</ul>
<h3><a id="%E4%B8%BE%E4%BE%8B1" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>举例1</h3>
<p>从键盘输入一些字符，逐个把它们送到磁盘上，直到用户输入一个“#”为止</p>
<pre class="line-numbers"><code class="language-c">#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;

int main()
{
    FILE *fp; //定义指向文件的指针
    char ch;
    fp = fopen(&quot;myfile.txt&quot;, &quot;w&quot;); //打开文件
    if (fp == NULL)
    {
        printf(&quot;file open error&quot;);
        exit(0); //终止程序
    }
    while ((ch = getchar()) != '#')
    {
        fputc(ch, fp); //写入字符
    }
    fclose(fp); //关闭文件
    return 0;
}
</code></pre>
<h3><a id="%E4%B8%BE%E4%BE%8B2" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>举例2</h3>
<p>将一个磁盘文件（file1.dat）中的信息复制到另一个磁盘文件（file2.dat）中</p>
<pre class="line-numbers"><code class="language-c">#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;

int main()
{
    FILE *in, *out; //定义指向文件的指针
    char ch;
    in = fopen(&quot;file1.dat&quot;, &quot;r&quot;);
    out = fopen(&quot;file2.dat&quot;, &quot;w&quot;);

    if (in == NULL || out == NULL)
    {
        printf(&quot;无法打开文件&quot;);
        exit(0);
    }

    while (!feof(in)) //判断in的文件内部位置指针是否指向eof
    {
        ch = fgetc(in);
        fputc(ch, out);
        putchar(ch); //将ch显示在屏幕上
    }
    putchar(10);
    fclose(in);  //关闭文件
    fclose(out); //关闭文件
    return 0;
}
</code></pre>
<h2><a id="%E5%AD%97%E7%AC%A6%E4%B8%B2%E8%AF%BB%E5%86%99%E5%87%BD%E6%95%B0%EF%BC%88ascii%E6%96%87%E4%BB%B6%EF%BC%89" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>字符串读写函数（ASCII文件）</h2>
<h3><a id="fgets%E5%87%BD%E6%95%B0" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>fgets()函数</h3>
<h4><a id="%E5%87%BD%E6%95%B0%E5%8E%9F%E5%9E%8B" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>函数原型</h4>
<p>从<code>fp</code>指向的文件中读取<code>n</code>个字符到<code>str</code>所指向的空间中</p>
<pre class="line-numbers"><code class="language-c">char *fgets(char *str, int n, FILE *fp); 
</code></pre>
<h4><a id="%E5%87%BD%E6%95%B0%E5%8A%9F%E8%83%BD" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>函数功能</h4>
<p>从指定的文件读入一个字符</p>
<h5><a id="%E4%B8%89%E4%B8%AA%E7%BB%93%E6%9D%9F%E6%A0%87%E8%AF%86" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>三个结束标识</h5>
<ul>
<li>读够n个字符</li>
<li>读到换行符</li>
<li>读到文件结束标识（eof）</li>
</ul>
<h4><a id="%E8%BF%94%E5%9B%9E%E5%80%BC" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>返回值</h4>
<ul>
<li>若执行<code>fgets()</code>函数成功，返回值为<code>str</code>数组首元素的地址</li>
<li>若执行失败（遇到文件尾或读数据出错），则返回NULL</li>
</ul>
<h3><a id="fputs%E5%87%BD%E6%95%B0" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>fputs()函数</h3>
<h4><a id="%E5%87%BD%E6%95%B0%E5%8E%9F%E5%9E%8B" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>函数原型</h4>
<p>将<code>str</code>字符串的内容写入到<code>fp</code>指向的文件中</p>
<pre class="line-numbers"><code class="language-c">int fputs(const str, FILE *fp);
</code></pre>
<h4><a id="%E5%87%BD%E6%95%B0%E5%8A%9F%E8%83%BD" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>函数功能</h4>
<ul>
<li>向指定的文件输出一个字符串</li>
<li>向磁盘文件写入数据时，只输出字符串中的有效字符，不包括字符串结束标志<code>\0</code></li>
</ul>
<h4><a id="%E8%BF%94%E5%9B%9E%E5%80%BC" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>返回值</h4>
<p>若执行<code>fputs()</code>函数成功，返回值为输出字符的个数</p>
<h3><a id="%E4%B8%BE%E4%BE%8B1" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>举例1</h3>
<p>从键盘读入若干个字符，对它们按字母大小写顺序排序，然后把排好序的字符串保存到磁盘文件中</p>
<h4><a id="%E5%88%86%E6%9E%90" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>分析</h4>
<ul>
<li>从键盘读入n个字符串，存放在一个二位字符数组中，每一个一个数组存放一个字符串</li>
<li>对字符数组中带的n个字符串按字母顺序排序，排好序的字符串仍存放在字符数组中</li>
<li>将字符数组中的字符串顺序输出</li>
</ul>
<pre class="line-numbers"><code class="language-c">#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;string.h&gt;
#define N 3

int main()
{
    FILE *fp; //定义指向文件的指针
    char str[N][10], temp[10];
    int i, j, pos;
    printf(&quot;输入字符串：\n&quot;);

    //从键盘输入字符串
    for (i = 0; i &lt; N; i++)
        gets(str[i]);

    //选择排序
    for (i = 0; i &lt; N - 1; i++)
    {
        pos = i;
        for (j = i + 1; j &lt; N; j++)
        {
            //使用strcmp()对字符串进行比较
            if (strcmp(str[pos], str[j]) &gt; 0)
                pos = j;

            //使用strcpy()对调位置
            if (pos != i)
            {
                strcpy(temp, str[i]);
                strcpy(str[i], str[pos]);
                strcpy(str[pos], temp);
            }
        }
    }

    if ((fp = fopen(&quot;string.dat&quot;, &quot;w&quot;)) == NULL)
    {
        printf(&quot;无法打开文件&quot;);
        exit(0);
    }

    for (i = 0; i &lt; N; i++)
    {
        fputs(str[i], fp);
        fputs(&quot;\n&quot;, fp);
        printf(&quot;%s\n&quot;, str[i]);
    }
    fclose(fp);

    return 0;
}
</code></pre>
<h2><a id="%E6%A0%BC%E5%BC%8F%E5%8C%96%E8%AF%BB%E5%86%99%E5%87%BD%E6%95%B0%EF%BC%88ascii%E6%96%87%E4%BB%B6%EF%BC%89" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>格式化读写函数（ASCII文件）</h2>
<h3><a id="fscanf%E5%87%BD%E6%95%B0" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>fscanf()函数</h3>
<h4><a id="%E5%87%BD%E6%95%B0%E8%B0%83%E7%94%A8" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>函数调用</h4>
<pre class="line-numbers"><code class="language-c">fprintf(文件指针, 格式字符串, 输出表列);
</code></pre>
<h5><a id="%E4%BE%8B%E5%A6%82" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>例如</h5>
<pre class="line-numbers"><code class="language-c">fprintf(fp, &quot;%d, %6.2f&quot;, i, t);
</code></pre>
<h4><a id="%E5%87%BD%E6%95%B0%E5%8A%9F%E8%83%BD" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>函数功能</h4>
<p>将字符写入到磁盘文件中</p>
<h4><a id="%E8%BF%94%E5%9B%9E%E5%80%BC" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>返回值</h4>
<p>如果读到文件结尾，返回EOF，否则返回字符个数</p>
<h3><a id="fprintf%E5%87%BD%E6%95%B0" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>fprintf()函数</h3>
<h4><a id="%E5%87%BD%E6%95%B0%E8%B0%83%E7%94%A8" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>函数调用</h4>
<p>fscanf(文件指针, 格式字符串, 输入表列);</p>
<h5><a id="%E4%BE%8B%E5%A6%82" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>例如</h5>
<pre class="line-numbers"><code class="language-c">fscanf(fp, &quot;%d, %f&quot;, &amp;i, &amp;t);
</code></pre>
<h4><a id="%E5%87%BD%E6%95%B0%E5%8A%9F%E8%83%BD" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>函数功能</h4>
<p>从磁盘文件中读取字符</p>
<h2><a id="%E6%95%B0%E6%8D%AE%E5%9D%97%E8%AF%BB%E5%86%99%E5%87%BD%E6%95%B0%EF%BC%88%E4%BA%8C%E8%BF%9B%E5%88%B6%E6%96%87%E4%BB%B6%EF%BC%89" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>数据块读写函数（二进制文件）</h2>
<p>数据块读写函数用二进制方式读写文件</p>
<h3><a id="fread%E5%87%BD%E6%95%B0" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>fread()函数</h3>
<h4><a id="%E5%87%BD%E6%95%B0%E8%B0%83%E7%94%A8" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>函数调用</h4>
<pre class="line-numbers"><code class="language-c">fread(buffer, size, count, fp);
</code></pre>
<h5><a id="%E5%8F%82%E6%95%B0%E8%AF%B4%E6%98%8E" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>参数说明</h5>
<ul>
<li><strong>buffer：</strong> 一个指针，指向读入数据的存放地址</li>
<li><strong>size：</strong> 要读写的字节数</li>
<li><strong>count：</strong> 要进行读写多少个<strong>size</strong>字节的数据项</li>
<li><strong>fp：</strong> 文件型指针</li>
</ul>
<h4><a id="%E5%87%BD%E6%95%B0%E5%8A%9F%E8%83%BD" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>函数功能</h4>
<p>从<strong>fp</strong>指向的文件当中读取<strong>count</strong>个大小为<strong>size</strong>的数据存储到<strong>buffer</strong>指向的空间中</p>
<h5><a id="%E4%BD%BF%E7%94%A8%E4%B8%BE%E4%BE%8B" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>使用举例</h5>
<p>若文件以二进制形式打开</p>
<pre class="line-numbers"><code class="language-c">fread(file, 4, 2, fp);
</code></pre>
<p>从fp所指向的文件中读取2个4字节的数据，并存储到数组file中</p>
<h4><a id="%E8%BF%94%E5%9B%9E%E5%80%BC" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>返回值</h4>
<p>实际写入的元素个数（<strong>count</strong>），如果返回值与<strong>count</strong>不相同，则可能文件结尾或发生错误</p>
<h3><a id="fwrite%E5%87%BD%E6%95%B0" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>fwrite()函数</h3>
<h4><a id="%E5%87%BD%E6%95%B0%E8%B0%83%E7%94%A8" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>函数调用</h4>
<pre class="line-numbers"><code class="language-c">fwrite(buffer, size, count, fp)
</code></pre>
<h5><a id="%E5%8F%82%E6%95%B0%E8%AF%B4%E6%98%8E" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>参数说明</h5>
<ul>
<li><strong>buffer：</strong> 一个指针，指向输出数据的地址</li>
<li><strong>size：</strong> 要读写的字节数</li>
<li><strong>count：</strong> 要进行读写多少个<strong>size</strong>字节的数据项</li>
<li><strong>fp：</strong> 文件型指针</li>
</ul>
<h4><a id="%E5%87%BD%E6%95%B0%E5%8A%9F%E8%83%BD" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>函数功能</h4>
<p>从<strong>buffer</strong>指向的空间中读取<strong>count</strong>个大小为<strong>size</strong>的数据写入<strong>fp</strong>指向的文件中</p>
<h5><a id="%E4%BD%BF%E7%94%A8%E4%B8%BE%E4%BE%8B" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>使用举例</h5>
<p>若文件以二进制形式打开</p>
<pre class="line-numbers"><code class="language-c">fwrite(file, 4, 2, fp);
</code></pre>
<p>从file所指向的数组中读取2个4字节的数据，并写入fp所指向的文件中</p>
<h4><a id="%E8%BF%94%E5%9B%9E%E5%80%BC" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>返回值</h4>
<p>实际读取的元素个数（<strong>count</strong>），如果返回值与<strong>count</strong>不相同，则可能文件结尾或发生错误</p>
<h3><a id="%E4%B8%BE%E4%BE%8B" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>举例</h3>
<p>从键盘输入3个学生的有关数据，然后把它们转存到磁盘文件中</p>
<pre class="line-numbers"><code class="language-c">#include &lt;stdio.h&gt;
#define SIZE 3

//定义全局结构体数组stu
struct student_type
{
    char name[10];
    int num;
    int age;
    char addr[15];
} stu[SIZE];

//定义save()函数，将学生信息输出到文件中
void save()
{
    FILE *fp;
    int i;
    if ((fp = fopen(&quot;stu.dat&quot;, &quot;wb&quot;)) == NULL)
    {
        printf(&quot;无法打开文件\n&quot;);
        return;
    }
    for (i = 0; i &lt; SIZE; i++)
    {
        //每次写入一个结构体数据到文件中，数据大小用sizeof进行度量
        if (fwrite(&amp;stu[i], sizeof(struct student_type), 1, fp) != 1)
            printf(&quot;写入错误&quot;);
    }
    printf(&quot;\n&quot;);
    fclose(fp);
    return;
}

//定义read()函数，从文件中读取学生信息
void read()
{
    FILE *fp;
    struct student_type s;
    int i;
    if ((fp = fopen(&quot;stu.dat&quot;, &quot;rb&quot;)) == NULL)
    {
        printf(&quot;无法打开文件\n&quot;);
        return;
    }
    for (i = 0; i &lt; SIZE; i++)
    {
        //每次读取一个数据体结构到数组中，数据大小用sizeof进行度量
        if (fread(&amp;s, sizeof(struct student_type), 1, fp) != 1)
            printf(&quot;读取错误&quot;);
        else
            printf(&quot;%s %d %d %s\n&quot;, s.name, s.num, s.age, s.addr);
    }
    fclose(fp);
    return;
}

int main()
{
    int i;
    printf(&quot;请输入学生信息：\n&quot;);
    for (i = 0; i &lt; SIZE; i++)
        scanf(&quot;%s %d %d %s&quot;, stu[i].name, &amp;stu[i].num, &amp;stu[i].age, stu[i].addr);

    save();
    read();
    return 0;
}
</code></pre>
<h2><a id="%E8%AF%BB%E5%86%99%E5%87%BD%E6%95%B0%E7%9A%84%E9%80%89%E7%94%A8%E5%8E%9F%E5%88%99" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>读写函数的选用原则</h2>
<p>用<code>fprintf()</code>和<code>fscanf()</code>函数对磁盘文件读写，使用方便，容易理解；但由于输入时需要将ASCII码转换为二进制形式，输出时有需要将二进制形式转换成字符，花费时间较多</p>
<p>因此，在内存与磁盘频繁交换数据的情况，尽可能不适用<code>fprintf()</code>和<code>fscanf()</code>函数，而使用<code>fread()</code>和<code>fwrite()</code>函数</p>

				</article>
				<div class="comments-wrap">
					<div class="share-comments">
						

						

						
					</div>
				</div><!-- end comments wrap -->
			</div>
		</div><!-- end columns -->
	</div><!-- end container -->
</section>  














<script src="asset/prism.js"></script>









</body>

</html>